﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Web.Mvc;
using System.Linq;
using KaytechSoftware.Cms.App.Common;
using KaytechSoftware.Cms.Common.Extensions;

namespace KaytechSoftware.Cms.App.Areas.Admin.Models.Base
{
    public abstract class GridEntityModel
    {
        protected IDictionary<CollectionKey, IList<SelectListItem>> RegisteredCollections;

        protected GridEntityModel()
        {
            RegisteredCollections = new Dictionary<CollectionKey, IList<SelectListItem>>();
        }

        public string ControllerName { get; set; }

        public void RegisterCollection<TItem>(CollectionKey key, IList<TItem> items, Func<TItem, long> valueSelector, Func<TItem, string> textSelector)
        {
            RegisteredCollections[key] = items.Select(i => new SelectListItem { Value = valueSelector(i).ToString(CultureInfo.InvariantCulture), Text = textSelector(i) }).ToList();
        }

        public GridEntityDetailsModel GetDetails()
        {
            var details = new GridEntityDetailsModel();
            var properties = GetType().GetProperties();
            foreach (var propertyInfo in properties)
            {
                var skip = propertyInfo.GetCustomAttributes(typeof (SkipInDetailsAttribute), true);
                if (skip.Length > 0)
                    continue;

                var renderers = propertyInfo.GetCustomAttributes(typeof (RendererAttribute), true);
                if (renderers.Length == 0)
                    continue;

                var descriptor = new GridEntityFiledDescriptor();
                var renderer = (RendererAttribute)renderers[0];

                var labels = propertyInfo.GetCustomAttributes(typeof(LabelAttribute), true);
                if (labels.Length > 0)
                    descriptor.LabelResourceKey = ((LabelAttribute)labels[0]).ResourceKey;

                descriptor.Renderer = renderer.Type;
                descriptor.Name = propertyInfo.Name;
                switch (descriptor.Renderer)
                {
                        case RendererType.Hidden: case RendererType.TextBox:
                            descriptor.TextValue = propertyInfo.GetValue(this).ToStringSafely();
                        break;
                        case RendererType.Integer:
                            descriptor.IntegerValue = propertyInfo.GetValue(this) as int?;
                        break;
                        case RendererType.Decimal:
                            descriptor.DecimalValue = propertyInfo.GetValue(this) as decimal?;
                        break;
                        case RendererType.DropDown:
                            descriptor.Items = RegisteredCollections[renderer.UseCollection];
                            descriptor.SelectedItem = propertyInfo.GetValue(this) as long?;
                        break;
                        case RendererType.Image:
                            descriptor.ImageValue = propertyInfo.GetValue(this) as PhotoDescriptor;
                        break;
                }

                details.FieldDescriptors.Add(descriptor);
            }

            return details;
        }
    }
}